package com.sh.data.engine.domain.dataquality.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sh.data.engine.common.exception.BusinessException;
import com.sh.data.engine.domain.base.model.UserContext;
import com.sh.data.engine.domain.dataasset.service.TableService;
import com.sh.data.engine.domain.dataquality.service.DataQualityJobExecService;
import com.sh.data.engine.domain.dataquality.service.DataQualityJobService;
import com.sh.data.engine.domain.dataquality.service.DataQualityRuleService;
import com.sh.data.engine.domain.dataquality.service.DataQualityService;
import com.sh.data.engine.domain.shims.db.model.TableInfoDomain;
import com.sh.data.engine.repository.dao.dataquality.entity.DataQualityJobEntity;
import com.sh.data.engine.repository.dao.dataquality.entity.DataQualityRuleEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @author tinglan.ys
 * @description:
 * @date 2022/2/25 下午2:15
 */
@Service
@Slf4j
public class DataQualityServiceImpl implements DataQualityService {

    @Autowired
    private DataQualityJobService dataQualityJobService;

    @Autowired
    private DataQualityRuleService dataQualityRuleService;

    @Autowired
    private DataQualityJobExecService dataQualityJobExecService;

    @Autowired
    private TableService tableService;

    @Override
    public void processDataQuality(
        Long projectId, Long tblId, List<Long> ruleIds, Integer cycle, Long partitionId) {

        // 根据表id等参数查出所有的规则
        List<DataQualityRuleEntity> rules =
            dataQualityRuleService.list(
                new LambdaQueryWrapper<DataQualityRuleEntity>()
                    .eq(DataQualityRuleEntity::getProjectId, projectId)
                    .eq(DataQualityRuleEntity::getTblId, tblId)
                    .eq(partitionId != null, DataQualityRuleEntity::getPartitionId, partitionId)
                    .in(CollectionUtils.isNotEmpty(ruleIds), DataQualityRuleEntity::getId, ruleIds));

        // 该表无规则
        if (CollectionUtils.isEmpty(rules)) {
            return;
        }

        String tableName = rules.get(0).getTblName();
        // 根据tblId 拿到tableName 这里不需要查询一遍表，规则里面有表name的信息
    /*
        TblPropEntity tblPropByTblId = tblPropService.getTblPropByTblId(projectId, tblId);
        if (tblPropByTblId != null) {
          tableName = tblPropByTblId.getTableName();
        } else {
          return;
        }
    */

        // 第一步：用dbManager查出表信息，为了拿到表描述
        TableInfoDomain tableInfo = tableService.getTableInfo(projectId, tableName);

        if (tableInfo == null) {
            throw new BusinessException("查询不到该表信息，任务失败");
        }

        // 表描述信息
        String tblComment = tableInfo.getTableComment();

        DataQualityJobEntity dataqualityJob = new DataQualityJobEntity();
        dataqualityJob.setCreatorId(UserContext.getUserId());
        dataqualityJob.setCreateTime(new Date());
        dataqualityJob.setUpdaterId(UserContext.getUserId());
        dataqualityJob.setUpdateTime(new Date());

        dataqualityJob.setTblId(tblId);
        dataqualityJob.setTblName(tableName);
        dataqualityJob.setTblComment(tblComment); // 对于数据质量而言 存入表描述信息没有意义
        dataqualityJob.setTaskCycle(cycle);
        // 工作流(任务)修改时间？
        dataqualityJob.setTaskUpdateTime(null);
        // 0-运行中 1-正常 2-异常 3-sql语句出错 */
        dataqualityJob.setStatus(0);
        dataqualityJob.setRuleNum(rules.size());
        dataqualityJob.setErrorNum(0);
        dataqualityJob.setIsLast(1);
        dataqualityJob.setIsSendAlarm(0);
        dataqualityJob.setProjectId(projectId);
        dataQualityJobExecService.executeDataqualityJob(projectId, tableName, dataqualityJob, rules);
    }

    @Override
    public void insertNewestJob(DataQualityJobEntity dataQualityJob, String userId) {

        List<DataQualityJobEntity> oldLast =
            dataQualityJobService.list(
                new LambdaQueryWrapper<DataQualityJobEntity>()
                    .eq(userId != null,
                        DataQualityJobEntity::getCreatorId,
                        userId)
                    .eq(
                        dataQualityJob.getProjectId() != null,
                        DataQualityJobEntity::getProjectId,
                        dataQualityJob.getProjectId())
                    .eq(
                        dataQualityJob.getTblId() != null,
                        DataQualityJobEntity::getTblId,
                        dataQualityJob.getTblId())
                    .eq(DataQualityJobEntity::getIsLast, 1));

        // 把老得任务isLast状态变0 (针对某一张表，查询的时候只展示最新的任务)
        if (CollectionUtils.isNotEmpty(oldLast)) {
            for (DataQualityJobEntity job : oldLast) {
                DataQualityJobEntity update = new DataQualityJobEntity();
                update.setIsLast(0);
                update.setId(job.getId());
                dataQualityJobService.updateById(update);
            }
        }
        dataQualityJobService.save(dataQualityJob);
    }

    @Override
    public Integer getLastJobStatus(Long projectId, Long tblId) {

        final DataQualityJobEntity one =
            dataQualityJobService.getOne(
                new LambdaQueryWrapper<DataQualityJobEntity>()
                    .eq(DataQualityJobEntity::getProjectId, projectId)
                    .eq(DataQualityJobEntity::getTblId, tblId)
                    .orderByDesc(DataQualityJobEntity::getId));

        if (one != null) {
            return one.getStatus();
        }
        return null;
    }
}
